package com.zbkj.admin.controller.platform.assistant.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zbkj.admin.controller.platform.assistant.service.AssistantConversationService;
import com.zbkj.admin.controller.platform.assistant.service.AssistantMessageService;
import com.zbkj.admin.controller.platform.assistant.service.AssistantSettingService;
import com.zbkj.common.constants.AssistantConstants;
import com.zbkj.common.exception.CrmebException;
import com.zbkj.common.model.admin.SystemAdmin;
import com.zbkj.common.model.assistant.AssistantConversation;
import com.zbkj.common.model.assistant.AssistantGroup;
import com.zbkj.common.model.assistant.AssistantGroupAccount;
import com.zbkj.common.model.assistant.AssistantSetting;
import com.zbkj.common.model.coupon.CouponUser;
import com.zbkj.common.model.user.User;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.result.AssistantResultCode;
import com.zbkj.common.utils.CommonUtil;
import com.zbkj.common.utils.SecurityUtil;
import com.zbkj.service.assistant.model.request.AssistantConversationCompleteRequest;
import com.zbkj.service.assistant.model.request.AssistantConversationHistorySearchRequest;
import com.zbkj.service.assistant.model.request.AssistantConversationSearchRequest;
import com.zbkj.service.assistant.model.response.AssistantUserInfoResponse;
import com.zbkj.service.assistant.model.vo.AssistantConversationVO;
import com.zbkj.service.assistant.model.vo.AssistantMessageVO;
import com.zbkj.service.assistant.service.AssistantConversationBaseServiceImpl;
import com.zbkj.service.service.CouponUserService;
import com.zbkj.service.service.OrderService;
import com.zbkj.service.service.RefundOrderService;
import com.zbkj.service.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
* @author keNan
* @description AssistantConversationServiceImpl 接口实现
* @date 2025-06-11
*/
@Slf4j
@Primary
@Service
@RequiredArgsConstructor
public class AssistantConversationServiceImpl extends AssistantConversationBaseServiceImpl implements AssistantConversationService {

    private final UserService userService;
    @Lazy
    @Autowired
    private AssistantMessageService assistantMessageService;
    private final AssistantSettingService assistantSettingService;
    private final OrderService orderService;
    private final RefundOrderService refundOrderService;
    private final CouponUserService couponUserService;

    @Override
    public AssistantConversation updateTransfer(AssistantConversation conversation, AssistantGroupAccount toAccount) {
        super.lambdaUpdate()
            .eq(AssistantConversation::getId, conversation.getId())
            .set(AssistantConversation::getServiceAccountId, toAccount.getAccountId())
            .set(AssistantConversation::getAllServiceAccountIds, conversation.getAllServiceAccountIds() + "," + toAccount.getAccountId())
            .set(AssistantConversation::getTransferCount, conversation.getTransferCount() + 1)
            .set(AssistantConversation::getServiceName, toAccount.getNickname())
            .set(AssistantConversation::getServiceAvatar, toAccount.getAvatar())
            .update();
        return super.getById(conversation.getId());
    }

    @Override
    @Transactional
    public Boolean processQueue(AssistantSetting setting, AssistantConversation conversation) {
        // 重新查询一次数据库
        AssistantConversation dbConversation = super.getById(conversation.getId());
        AssistantGroup.CodeEnum codeEnum = this.getGroupCodeByConversation(dbConversation);

        Integer serviceAccountId = super.checkServiceAccountId(setting, codeEnum);
        // 找到客服id，更新会话
        if (!AssistantConstants.INVALID_SERVICE_ACCOUNT_ID.equals(serviceAccountId)) {
            super.updateQueueToService(dbConversation, serviceAccountId, setting, true);
            return true;
        }
        return false;
    }

    @Override
    public void timeout(AssistantSetting setting, AssistantConversation conversation) {
        if (!setting.getIsConversationTimeoutAutoClose()) {
            return;
        }

        this.conversationEnd(setting, conversation, setting.getConversationTimeoutMsg(), AssistantConstants.Conversation.END_TYPE_TIMEOUT);
    }

    @Override
    public List<AssistantConversation> findServiceList() {
        return super.lambdaQuery()
            .eq(AssistantConversation::getStatus, AssistantConstants.Conversation.STATUS_SERVICE)
            .orderByAsc(AssistantConversation::getCreateTime, AssistantConversation::getId)
            .list();

    }

    @Override
    public List<AssistantConversation> findQueueList() {
        AssistantSetting setting = assistantSettingService.getSetting();

        // 先到后服务
        if (AssistantConstants.Setting.QUEUE_ASSIGN_RULE_EARLY_TO_LATE.equals(setting.getQueueAssignRule())) {
            return super.lambdaQuery()
                .eq(AssistantConversation::getStatus, AssistantConstants.Conversation.STATUS_QUEUE)
                .orderByDesc(AssistantConversation::getCreateTime, AssistantConversation::getId)
                .list();
        }

        // 先到先服务
        return super.lambdaQuery()
            .eq(AssistantConversation::getStatus, AssistantConstants.Conversation.STATUS_QUEUE)
            .orderByAsc(AssistantConversation::getCreateTime, AssistantConversation::getId)
            .list();
    }

    @Override
    @Transactional
    public void complete(AssistantConversationCompleteRequest request) {
        AssistantConversation conversation = super.getById(request.getConversationId());
        if (ObjUtil.isNull(conversation) || !AssistantConstants.Conversation.STATUS_SERVICE.equals(conversation.getStatus())) {
            throw new CrmebException(AssistantResultCode.CONVERSATION_CANT_COMPLETE);
        }

        AssistantSetting setting = assistantSettingService.getSetting();
        String completeContent = "当前会话已结束，如需继续对话，请重新发起会话";
        this.conversationEnd(setting, conversation, completeContent, AssistantConstants.Conversation.END_TYPE_COMPLETE);
    }

    @Override
    public PageInfo<AssistantConversationVO> getAdminConversationHistoryPage(AssistantConversationHistorySearchRequest request, PageParamRequest pageParamRequest) {
        Page<AssistantConversationVO> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        List<AssistantConversationVO> list = baseMapper.findHistoryList(request);
        list.forEach(x -> x.setUserPhone(CommonUtil.hidePhone(x.getUserPhone())));
        return CommonPage.copyPageInfo(page, list);
    }

    @Override
    public List<AssistantConversationVO> getAdminConversationList(AssistantConversationSearchRequest request) {
        SystemAdmin admin = SecurityUtil.getLoginUserVo().getUser();
        List<AssistantConversation> list = super.lambdaQuery()
            .eq(AssistantConversation::getServiceAccountId, admin.getId())
            .eq(AssistantConversation::getStatus, 1)
            .list();

        List<AssistantConversationVO> vos = list.stream().map(x -> {
            AssistantConversationVO vo = new AssistantConversationVO();
            BeanUtil.copyProperties(x, vo);

            // 用户和统计数据
            User user = userService.getById(x.getUserId());
            user.setPhone(CommonUtil.hidePhone(user.getPhone()));
            if (ObjUtil.isNotEmpty(user)) {
                AssistantUserInfoResponse userInfo = new AssistantUserInfoResponse();
                BeanUtil.copyProperties(user, userInfo);
                vo.setUserInfo(userInfo).setUserPhone(userInfo.getPhone());

                // 订单数和金额,退款数和金额
                Pair<Integer, BigDecimal> orderPair = orderService.getOrderCountAndAmountByUid(userInfo.getId());
                Pair<Integer, BigDecimal> refundPair = refundOrderService.getRefundCountAndAmountByUid(userInfo.getId());

                userInfo.setTotalOrderCount(orderPair.getLeft())
                    .setTotalOrderAmount(orderPair.getRight())
                    .setTotalRefundCount(refundPair.getLeft())
                    .setTotalRefundAmount(refundPair.getRight())
                    .setDeliveryCouponCount(0);
                List<CouponUser> coupons = couponUserService.getListByUid(userInfo.getId(), 2);
                if (ObjUtil.isNotEmpty(coupons)) {
                    userInfo.setDeliveryCouponCount(coupons.size());
                }

            }

            // 未读消息数量
            vo.setUnreadCount(assistantMessageService.getUnreadCount(x.getUserId()));

            // 最新消息
            AssistantMessageVO lastMessage = assistantMessageService.getLastMessage(x.getId());
            if (ObjUtil.isNotEmpty(lastMessage)){
                vo.setLastMessage(lastMessage);
                vo.setLastMessageTime(lastMessage.getCreateTime());
                vo.setLastMessageContent(lastMessage.getViewTextContent());
            }

            return vo;
        }).collect(Collectors.toList());

        return vos;
    }

    private AssistantGroup.CodeEnum getGroupCodeByConversation(AssistantConversation conversation) {
        if (AssistantConstants.Conversation.SOURCE_PRODUCT.equals(conversation.getSource())) {
            return AssistantGroup.CodeEnum.BEFORE;

        } else if (AssistantConstants.Conversation.SOURCE_ORDER.equals(conversation.getSource())) {
            return AssistantGroup.CodeEnum.AFTER;

        } else if (AssistantConstants.Conversation.SOURCE_REFUND_ORDER.equals(conversation.getSource())) {
            return AssistantGroup.CodeEnum.AFTER;
        }
        return AssistantGroup.CodeEnum.DEFAULT;
    }

    private void conversationEnd(AssistantSetting setting, AssistantConversation conversation, String completeContent, Integer endType) {
        super.lambdaUpdate()
            .eq(AssistantConversation::getId, conversation.getId())
            .set(AssistantConversation::getEndType, endType)
            .set(AssistantConversation::getStatus, AssistantConstants.Conversation.STATUS_COMPLETE)
            .set(AssistantConversation::getEndTime, new Date())
            .update();

        assistantMessageService.sendBySystem(conversation, AssistantConstants.Message.CONTENT_TYPE_SYSTEM, completeContent, true, AssistantConstants.Message.CONTENT_TYPE_SERVICE_REFRESH_CONVERSATION);
        if (setting.getIsOpenUserFeedback()) {
            assistantMessageService.sendBySystem(conversation, AssistantConstants.Message.CONTENT_TYPE_COMMENT, "", true);
        }

        // 结束之后，让下一个排队的人进入服务
        List<AssistantConversation> queueList = this.findQueueList();
        if (ObjUtil.isNotEmpty(queueList)) {
            this.processQueue(setting, queueList.get(0));
        }
    }

}

